package com.tpc.jginterface.util.crypto;

import cn.hutool.crypto.ECKeyUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.SM2;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author duwenlei
 * @version 1.0
 * @ClassName SM2Util
 * @Date 2024/4/22 17:20
 * @Description SM2 工具
 */
public class SM2Util {
    public static final String PRIVATE_KEY = "privateKey";
    public static final String PUBLIC_KEY = "publicKey";

    /**
     * SM2 密钥生成
     *
     * @return SM2 密钥
     */
    public static Map<String, byte[]> generateSM2() {
        SM2 sm2 = SmUtil.sm2();
        byte[] d = sm2.getD();
        byte[] q = sm2.getQ(true);
        return new HashMap() {{
            put(PRIVATE_KEY, d);
            put(PUBLIC_KEY, q);
        }};
    }


    /**
     * 签名
     *
     * @param privateKey 私钥
     * @param originData 原数据
     * @return 签名后数据
     */
    public static byte[] sign(byte[] privateKey, String originData) {
        SM2 sm2 = new SM2(privateKey, null, null);
        sm2.usePlainEncoding();
        String digest = SM3Util.digest(originData);
        return sm2.sign(digest.getBytes(StandardCharsets.UTF_8), null);
    }

    /**
     * 签名
     *
     * @param privateKeyHex 私钥 16进制
     * @param originData    原数据
     * @return
     */
    public static byte[] sign(String privateKeyHex, String originData) throws DecoderException {
        return sign(Hex.decodeHex(privateKeyHex), originData);
    }

    /**
     * 验签
     *
     * @param publicKey  公钥
     * @param originData 原数据
     * @param signData   签名数据
     * @return 结果
     */
    public static boolean verify(byte[] publicKey, byte[] originData, byte[] signData) {
        SM2 sm2 = new SM2(null, ECKeyUtil.toSm2PublicParams(publicKey));
        sm2.usePlainEncoding();
        return sm2.verify(originData, signData);
    }

    /**
     * 验签
     *
     * @param publicKey   公钥
     * @param originData  原数据
     * @param signDataHex 签名数据 16进制
     * @return 结果
     */
    public static boolean verify(byte[] publicKey, String originData, String signDataHex) throws DecoderException {
        String digest = SM3Util.digest(originData);
        return verify(publicKey, digest.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(signDataHex));
    }

    /**
     * 验签
     *
     * @param publicKeyHex 公钥 16进制
     * @param originData   原数据
     * @param signDataHex  签名数据 16进制
     * @return 结果
     */
    public static boolean verify(String publicKeyHex, String originData, String signDataHex) throws DecoderException {
        return verify(Hex.decodeHex(publicKeyHex), originData.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(signDataHex));
    }
}
